{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 对象的比较和拷贝"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1  对象的比较\n",
    "\n",
    "- '==' 操作符比较对象之间值是否相等\n",
    "-  'is' 操作符比较对象身份信息是否相等，它们是否同一个对象，是否指向一个内存地址\n",
    "- 对象的身份标识 id(object)  \n",
    "- 比较操作符'is'效率优于'=='，因为'is'操作符无法被重载，执行'is'操作只是简单的获取对象的 ID，并进行比较；而'=='操作符则会递归地遍历对象的所有值，并逐一比较"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "1669060205808 1669060205712\n"
     ]
    }
   ],
   "source": [
    "a = 257  #  -5 到 256 是整数池， 257 不在整数池中，所以 a 和 b 是不同的对象\n",
    "b = 257\n",
    "\n",
    "print(a == b)\n",
    "print(a is b)\n",
    "print(id(a),id(b))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 比较操作符'is'的速度效率，通常要优于'=='。因为'is'操作符不能被重载，这样，Python 就不需要去寻找，程序中是否有其他地方重载了比较操作符，并去调用。执行比较操作符'is'，就仅仅是比较两个变量的 ID 而已。\n",
    "- 但是'=='操作符却不同，执行a == b相当于是去执行a.__eq__(b)，而 Python 大部分的数据类型都会去重载__eq__这个函数，其内部的处理通常会复杂一些。比如，对于列表，__eq__函数会去遍历列表中的元素，比较它们的顺序和值是否相等"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 浅拷贝 和 深拷贝\n",
    "\n",
    "- 浅拷贝中的元素，是原对象中子对象的引用，因此，如果原对象中的元素是可变的，改变其也会影响拷贝后的对象，存在一定的副作用。\n",
    "  + 可以通过数据构造器（list、set）完成浅拷贝，对于可变序列可以使用切片完成浅拷贝，对于元组而言，tuple()和切片不创建浅拷贝，指向相同元组的引用，还可以使用import copy, 使用copy.copy()来进行浅拷贝。\n",
    "  + 浅拷贝是对元素的引用，所以对于子对象，如果子对象是不可变，没有影响，如果是可变的序列，会带来一些影响\n",
    "- 深度拷贝则会递归地拷贝原对象中的每一个子对象，因此拷贝后的对象和原对象互不相关。另外，深度拷贝中会维护一个字典，记录已经拷贝的对象及其 ID，来提高效率并防止无限递归的发生。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "RecursionError",
     "evalue": "maximum recursion depth exceeded in comparison",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mRecursionError\u001b[39m                            Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m      5\u001b[39m y = copy.deepcopy(x)\n\u001b[32m      7\u001b[39m \u001b[38;5;66;03m# 以下命令的输出是？\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m \u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\n",
      "\u001b[31mRecursionError\u001b[39m: maximum recursion depth exceeded in comparison"
     ]
    }
   ],
   "source": [
    "import copy\n",
    "x = [1]\n",
    "x.append(x)\n",
    "\n",
    "y = copy.deepcopy(x)\n",
    "\n",
    "# 以下命令的输出是？\n",
    "x == y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "import copy\n",
    "\n",
    "x = 257\n",
    "y = copy.copy(x)\n",
    "# y = copy.deepcopy(x)\n",
    "\n",
    "# 以下命令的输出是？\n",
    "print(x == y)\n",
    "print(x is y)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x = '1'\n",
    "y = copy.copy(x)\n",
    "\n",
    "# 以下命令的输出是？\n",
    "print(x == y)\n",
    "print(x is y)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x = (1)\n",
    "y = copy.copy(x)\n",
    "\n",
    "# 以下命令的输出是？\n",
    "print(x == y)\n",
    "print(x is y)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "x = [1,2,3]\n",
    "y = copy.copy(x)\n",
    "\n",
    "# 以下命令的输出是？\n",
    "print(x == y)\n",
    "print(x is y)\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
